﻿using System.Collections.Generic;
using UBlockly.Compotent;
using UBlockly.UI;
using UnityEngine;

namespace UBlockly.Sys
{

    public class PainttingSystem : CoreRunningSystem, IFrameUpdate
    {
        readonly uint painttingOffen = 3;
        Transform rootTransformForNode;
        bool isDuringPaintting = false;
        bool operateSlotTypeOrPackType = false;  //true : slot ; false : pack
        uint frameCount = 0;
        List<NSlotPair> beCheckingSortList = new List<NSlotPair>();
        protected override void OnInit(params object[] args)
        {
            base.OnInit(args);
            FrameUpdateMgr.Instance.RegistFrame(this);
            rootTransformForNode =
                Util.UBlocklyFacade.GetIns().Find("PaintingCavas/WorkSpace/ViewPort/Content");
        }

        public void HandlerBlock(BlockObject block)
        {
            BeforePaintting(block);
        }

        public void HandlerOver(BlockObject block)
        {
            AfterPaintting(block);
        }

        void BeforePaintting(BlockObject block)
        {
            isDuringPaintting = true;
            operateSlotTypeOrPackType = block.Node.Value.Scriptable.ResultType == Scriptable.ILFunResult.VoidR;
            UBtil.SetToTop(block.Node);
            if (operateSlotTypeOrPackType)
                HandlerSlotEnvironment(block);
            else
                HandlerPackEnvironment(block);
        }

        void AfterPaintting(BlockObject block)
        {
            isDuringPaintting = false;
            if (operateSlotTypeOrPackType)
            {
                BackSlotEvironment(block);
                if (isChecked)
                {
                    blockSys.DoSlot(nodeSys.FindNode(pair1.NodeId).Block, nodeSys.FindNode(pair2.NodeId).Block, 0);
                }
            }
            else
            {
                if(targetPackBlock != null && targetPack != null)
                {
                    blockSys.DoPack(targetPackBlock, targetPack, packIndex);
                }
                BackPackEvironment(block);
            }           
        }

        void HandlerSlotEnvironment(BlockObject block)
        {
            Debug.Log($"{block.Node.Value.Id}被拖动，链长-{block.Node.List.Count},链头-{block.Node.List.First.Value.Id}");
            var list = (block.Node.List as ULinkedList<Node>)?.Split(block.Node.Value, rootTransformForNode);
            list.ForEachCircle(node => {
                var pp = node.GetPairs();
                for (int i = 0; i < pp.Length; i++)
                {
                    pp[i].MuteAllRect();
                }
            });
            list.First.Value.GetPair().ActiveARect(true);
            list.Last.Value.GetPair().ActiveBRect(true);
            beCheckingSortList.Clear();
            beCheckingSortList.Add(list.First.Value.GetPair());
            beCheckingSortList.Add(list.Last.Value.GetPair());
            UBtil.HandlerBeginDragBlock(block);
            
            Debug.Log($"检测点个数{beCheckingSortList.Count},总被检测个数{blockSys.slotTypeBlockList.Count}");
        }

        void BackSlotEvironment(BlockObject block)
        {
            //1，把第一个节点下所有节点还原
            UBtil.HandlerEndDragBlock(block);
            block.Node.List.ForEachCircle(node => {
                var pp = node.GetPairs();
                for (int i = 0; i < pp.Length; i++)
                {
                    pp[i].MuteAllRect(false);
                }
            });
        }

        void HandlerPackEnvironment(BlockObject block)
        {
            targetPackBlock = block as PackTypeBlock;
            foreach (var nodePacker in blockSys.packerList)
            {
                if (nodePacker.GetParam(0).Block == block)
                {
                    nodePacker.UnPackNode(rootTransformForNode);
                }
            }
        }

        void BackPackEvironment(BlockObject block)
        {
            targetPack = null;
            targetPackBlock = null;
            targetPackList.Clear();
            packIndex = 0;
        }

        bool isChecked = false;
        NSlotPair pair1, pair2;
        void DuringSlotPaintting()
        {
            foreach (var checkpair in beCheckingSortList)
            {
                foreach (var becheck in blockSys.slotTypeBlockList)
                {
                    foreach (var beCheckPair in becheck.Node.Value.GetPairs())
                    {
                       if (checkpair.NodeId == beCheckPair.NodeId)
                           continue;
                        //Debug.Log($"正在检测{checkpair.NodeId} - {beCheckPair.NodeId}");
                        if(isChecked = UBtil.IsRecttransAcross(checkpair.ARect, beCheckPair.BRect))
                        {
                            pair1 = checkpair;
                            pair2 = beCheckPair;
                        }

                        #region 是否可以反过来
//                        if (!isChecked)
//                        {
//                            if (isChecked = UBtil.IsRecttransAcross(checkpair.BRect, beCheckPair.ARect))
//                            {
//                                pair1 = checkpair;
//                                pair2 = beCheckPair;
//                            }
//                        }
                        #endregion
                        if (isChecked)
                        {
                            UnityEngine.Debug.Log($"slot 已经匹配上");
                            return;
                        }
                    }
                }
            }
        }

        NodePacker targetPack;
        PackTypeBlock targetPackBlock;
        List<NodePacker> targetPackList = new List<NodePacker>();
        int packIndex = 0;
        void DuringPackPaintting()
        {
            targetPackList.Clear();
            targetPack = null;
            foreach (var becheck in blockSys.packerList)
            {
                packIndex = 0;
                foreach (var rectPacker in becheck.GetPackers())
                {
                    packIndex++;
                    if (rectPacker.ParamType != targetPackBlock.PackType)
                        continue;
                    if (isChecked = UBtil.IsAcross(rectPacker.BlockAnchor.RectTransform,
                        targetPackBlock.BlockAnchor.RectTransform.position))
                    {
                        Debug.Log($"pack 已经匹配上");
                        targetPackList.Add(becheck);
                    }
                }
            }

            if (targetPackList.Count != 0)
            {
                targetPackList.Sort(TopPack);
                targetPack = targetPackList[0];
            }
        }

        int TopPack(NodePacker a, NodePacker b)
        {
            if (a.GetPackAnchor(packIndex).transform.position.z > a.GetPackAnchor(packIndex).transform.position.z)
                return -1;
            return 1;
        }

        GameObject tempSlotTypeGo;
        void IFrameUpdate.UpdateDo(float deltatime)
        {
            if (!isDuringPaintting) return;
            if (++frameCount % painttingOffen == 0)
            {
                isChecked = false;
                if (operateSlotTypeOrPackType)
                {
                    if (tempSlotTypeGo != null)
                        GameObject.DestroyImmediate(tempSlotTypeGo);

                    DuringSlotPaintting();
                    if (isChecked) //
                    {
                        
                    }
                }
                else
                {
                    DuringPackPaintting();
                    if (isChecked)
                    {

                    }
                }
            }
        }
    }

}
